﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SYSoft.Comm;
using SYSoft.JWT;
using SYSoft.Model;
using SYSoft.Model.Model.Models;
using SYSoft.Model.Models.SystemManage;
using SYSoft.Services.SystemManage;

namespace SYSoft.Controllers.SystemManage
{
    /// <summary>
    /// 权限管理
    /// </summary>
    public class PermissionController : BaseController
    {
        readonly IUserRoleServices _userRoleServices;
        private ISysUserInfoServices _sysUserInfoServices;
        private IMenuServices menuServices;

        private IMenuRoleServices menuRoleServices;
        public PermissionController(IUserRoleServices userRoleServices, ISysUserInfoServices sysUserInfoServices, IMenuServices menuServices, IMenuRoleServices menuRoleServices)
        {
            this.menuServices = menuServices;
            this.menuRoleServices = menuRoleServices;
            this._sysUserInfoServices = sysUserInfoServices;
            this._userRoleServices = userRoleServices;
        }


        /// <summary>
        /// 根据token获取路由树
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageModel<List<NavigationBar>>> GetNavigationBar(string token)
        {
            var uId = JwtToken.SerializeJwt(token);
            var user = await _sysUserInfoServices.QueryById(uId);
            if (user == null)
                return MessageModel.CreateFailedResult<List<NavigationBar>>("不能查询到该用户");


            // 获取角色id集合
            List<int> roleIds = (await _userRoleServices.Query(d => d.UserId == uId)).Select(d => d.RoleId.ObjToInt()).Distinct().ToList();

            //筛选出改角色所有的菜单Id，去掉重复值   **(这样一个用户有多个角色，得到的菜单就是他的 合并后的集合）*****
            var menuIds = (await menuRoleServices.Query(x => roleIds.Contains(x.RoleId))).Select(d => d.MenuId).Distinct();
            if (menuIds.Any())
            {
                //通过获取的所有菜单Id ，得到菜单实体列表
                var menuModels = (await menuServices.Query(x => menuIds.Contains(x.Id))).OrderBy(d => d.OrderNo);
                if (menuModels.Any())
                {
                    List<NavigationBar> navigationBarsParent = new List<NavigationBar>();
                    foreach (var item in menuModels)
                    {
                        if (item.ParentId == 0)
                        {
                            navigationBarsParent.Add(new NavigationBar
                            {
                                id = item.Id,
                                name = item.MenuName,
                                title = item.MenuName,
                                path = item.path, //前端path 一定要 /开头
                                component = item.MenuUrl, // "Layout NoLayout"
                                iconCls = item.MenuIcon,
                                pid = item.ParentId,
                                order = item.OrderNo,
                                meta = new NavigationBarMeta() { title = item.MenuName, icon = item.MenuIcon },
                                children = new List<NavigationBar>()
                            });
                        }
                        else //子节点
                        {
                            (navigationBarsParent.FirstOrDefault(d => d.id == item.ParentId)).children.Add(new NavigationBar
                            {
                                id = item.Id,
                                name = item.MenuName,
                                title = item.MenuName,
                                path = item.path,
                                iconCls = item.MenuIcon,
                                pid = item.ParentId,
                                order = item.OrderNo,
                                component = item.MenuUrl,
                                meta = new NavigationBarMeta { title = item.MenuName, icon = item.MenuIcon },  //一定要有title
                                children = new List<NavigationBar>()
                            });
                        }
                    }
                    return MessageModel.CreateSuccessResult(navigationBarsParent);
                }
                else
                {
                    return MessageModel.CreateFailedResult<List<NavigationBar>>("获取失败");
                }
            }

            return MessageModel.CreateFailedResult<List<NavigationBar>>("获取失败");
        }


        /// <summary>
        /// 通过角色Id获取数据权限,菜单和按钮Id集合
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageModel<List<NavigationBar>>> getPermissionsByRoleId(int roleId)
        {
            //筛选出改角色所有的菜单Id，去掉重复值   **(这样一个用户有多个角色，得到的菜单就是他的 合并后的集合）*****
            var menuIds = (await menuRoleServices.Query(x => x.RoleId == roleId)).Select(d => d.MenuId).Distinct();
            if (menuIds.Any())
            {
                //通过获取的所有菜单Id ，得到菜单实体列表
                var menuModels = (await menuServices.Query(x => menuIds.Contains(x.Id))).OrderBy(d => d.OrderNo);
                if (menuModels.Any())
                {
                    List<NavigationBar> navigationBarsParent = new List<NavigationBar>();
                    foreach (var item in menuModels)
                    {
                        if (item.ParentId == 0)
                        {
                            navigationBarsParent.Add(new NavigationBar
                            {
                                id = item.Id,
                                name = item.MenuName,
                                title = item.MenuName,
                                path = item.path, //前端path 一定要 /开头
                                component = item.MenuUrl, // "Layout NoLayout"
                                iconCls = item.MenuIcon,
                                pid = item.ParentId,
                                order = item.OrderNo,
                                meta = new NavigationBarMeta() { title = item.MenuName, icon = item.MenuIcon },
                                children = new List<NavigationBar>()
                            });
                        }
                        else //子节点
                        {
                            (navigationBarsParent.FirstOrDefault(d => d.id == item.ParentId)).children.Add(new NavigationBar
                            {
                                id = item.Id,
                                name = item.MenuName,
                                title = item.MenuName,
                                path = item.path,
                                iconCls = item.MenuIcon,
                                pid = item.ParentId,
                                order = item.OrderNo,
                                component = item.MenuUrl,
                                meta = new NavigationBarMeta { title = item.MenuName, icon = item.MenuIcon },  //一定要有title
                                children = new List<NavigationBar>()
                            });
                        }
                    }
                    return MessageModel.CreateSuccessResult(navigationBarsParent);
                }
                else
                {
                    return MessageModel.CreateFailedResult<List<NavigationBar>>("获取失败");
                }
            }

            return MessageModel.CreateFailedResult<List<NavigationBar>>("获取失败");
        }


        /// <summary>
        /// 通过角色Id获取数据权限,菜单和按钮Id集合
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<MessageModel<List<NavigationBar>>> getAllMenus()
        {
            //筛选出改角色所有的菜单Id，去掉重复值   **(这样一个用户有多个角色，得到的菜单就是他的 合并后的集合）*****
            var menuIds = (await menuRoleServices.Query()).Select(d => d.MenuId).Distinct();
            if (menuIds.Any())
            {
                //通过获取的所有菜单Id ，得到菜单实体列表
                var menuModels = (await menuServices.Query(x => menuIds.Contains(x.Id))).OrderBy(d => d.OrderNo);
                if (menuModels.Any())
                {
                    List<NavigationBar> navigationBarsParent = new List<NavigationBar>();
                    foreach (var item in menuModels)
                    {
                        if (item.ParentId == 0)
                        {
                            navigationBarsParent.Add(new NavigationBar
                            {
                                id = item.Id,
                                name = item.MenuName,
                                title = item.MenuName,
                                path = item.path, //前端path 一定要 /开头
                                component = item.MenuUrl, // "Layout NoLayout"
                                iconCls = item.MenuIcon,
                                pid = item.ParentId,
                                order = item.OrderNo,
                                meta = new NavigationBarMeta() { title = item.MenuName, icon = item.MenuIcon },
                                children = new List<NavigationBar>()
                            });
                        }
                        else //子节点
                        {
                            (navigationBarsParent.FirstOrDefault(d => d.id == item.ParentId)).children.Add(new NavigationBar
                            {
                                id = item.Id,
                                name = item.MenuName,
                                title = item.MenuName,
                                path = item.path,
                                iconCls = item.MenuIcon,
                                pid = item.ParentId,
                                order = item.OrderNo,
                                component = item.MenuUrl,
                                meta = new NavigationBarMeta { title = item.MenuName, icon = item.MenuIcon },  //一定要有title
                                children = new List<NavigationBar>()
                            });
                        }
                    }
                    return MessageModel.CreateSuccessResult(navigationBarsParent);
                }
                else
                {
                    return MessageModel.CreateFailedResult<List<NavigationBar>>("获取失败");
                }
            }

            return MessageModel.CreateFailedResult<List<NavigationBar>>("获取失败");
        }


        /// <summary>
        /// 通过角色获取拥有的菜单ID菜单【无权限】
        /// </summary>
        /// <param name="roleid"></param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public async Task<MessageModel<List<int>>> GetPermissionIdByRoleId(int roleid)
        {
            var rmps = await menuRoleServices.Query(x => x.RoleId == roleid);
            if (rmps != null && rmps.Count > 0)
            {
                var permissionTrees = (from child in rmps
                                       orderby child.MenuId
                                       select child.MenuId).ToList();
                return MessageModel.CreateSuccessResult(permissionTrees);
            }
            return MessageModel.CreateFailedResult<List<int>>("获取失败");
        }

        ///// <summary>
        ///// 获取菜单树
        ///// </summary>
        ///// <returns></returns>
        //[HttpGet]
        //public async Task<MessageModel<PermissionTree>> GetAllMenu()
        //{
        //    var menulist = await menuServices.Query();
        //    var permissionTrees = (from child in menulist
        //                           orderby child.Id
        //                           select new PermissionTree
        //                           {
        //                               value = child.Id,
        //                               title = child.MenuName,
        //                               Pid = child.ParentId,
        //                               isbtn = false,
        //                               order = child.OrderNo,
        //                           }).ToList();
        //    PermissionTree rootRoot = new PermissionTree
        //    {
        //        value = 0,
        //        Pid = 0,
        //        title = "根节点"
        //    };

        //    permissionTrees = permissionTrees.OrderBy(d => d.order).ToList();


        //    RecursionHelper.LoopToAppendChildren(permissionTrees, rootRoot, 0, false);

        //    return MessageModel.CreateSuccessResult(rootRoot);
        //}



        /// <summary>
        /// 更新角色菜单权限分配
        /// </summary>
        /// <param name="roleid"></param>
        /// <param name="menuids"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<MessageModel> UpdatePermission(int roleid, [FromBody]List<int> menuids)
        {
            if (menuids.Count > 0)
            {
                bool del = true;
                var rolePermissions = await menuRoleServices.Query(d => d.RoleId == roleid);
                var ids = rolePermissions.Select(c => (object)c.Id);  // 获取所有记录的id
                if (rolePermissions.Any()) // 存在则先删除
                {
                    del= await menuRoleServices.DeleteByIds(ids.ToArray());
                }
                if(del)
                {
                    List<sys_MenuRole> sys_MenuRoles = new List<sys_MenuRole>();
                    for (int i = 0; i < menuids.Count; i++)
                    {
                        sys_MenuRole model = new sys_MenuRole
                        {
                            MenuId = menuids[i],
                            RoleId = roleid
                        };
                        sys_MenuRoles.Add(model);
                    }
                    if (await menuRoleServices.Add(sys_MenuRoles) > 0) return MessageModel.CreateSuccessResult();
                    else return new MessageModel("添加失败！！");
                }
                return new MessageModel("删除记录时候失败！！");
            }
            else return new MessageModel("权限数量不能为0");
        }
    }

    public class AssignView
    {
        public List<int> pids { get; set; }
        public int rid { get; set; }
    }

    public class AssignShow
    {
        public List<int> permissionids { get; set; }
        public List<string> assignbtns { get; set; }
    }
}
